#include <string.h>
#include <stdio.h>
#include "../../../../mac/mac.h"

int8 mac_init_test()
{
    mac_info_init();
    mac_retry_init();
    mac_indir_init();
    buf_init();
}

int8 mac_data_req_test(mac_data_req_t *req, uint16 user_data)
{
    buf_t *send;
    buf_t *recv;
    uint8 *tx_frm;
    uint8 l;
    mac_hdr_t hdr;
    int8 ret;
    uint16 *p;
    uint16 parse_user_data;
    mac_indir_t *i;

    MAC_DEBUG("mac_data_req_test: 1\n");
    send = buf_alloc(true);
    MAC_DEBUG("mac_data_req_test: 2\n");
    fflush(stdout);
    if (send == NULL) {
        return MAC_ERR;
    }
    /* put user data into the buffer */
    send->ptr--;
    p = (uint16 *)(send->ptr);
    *p = user_data;
    send->ptr--;
    send->length += 2;
    MAC_DEBUG("mac_data_req_test: the user_data in the buffer is 0x%x\n", *(uint16 *)p);

    MAC_DEBUG("mac_data_req_test: 2\n");
    mac_data_req(send, req);

    recv = buf_alloc(true);
    if (recv == NULL) {
        return MAC_ERR;
    }

    if (req->opt.indir == 0) {
        tx_frm = get_tx_frm();
        l = get_tx_frm_len();
        MAC_DEBUG("mac_data_req_test: length of the generated frame is %d\n", l);
        /* back off the pointer */
        recv->ptr -= (l-1);
        memcpy(recv->ptr, tx_frm, l);
    } else {
        i = mac_indir_find(&req->dest);
        if (i == NULL || i->buf == NULL) {
            return MAC_ERR;
        }
        recv = i->buf;
    }

    /* parse the frame */
    mac_parse_hdr(recv, &hdr);
    /* parse the user data */
    parse_user_data = *(uint16 *)(recv->ptr);
    recv->ptr = NULL;    
    
    MAC_DEBUG("mac_data_test: user_data = 0x%x\n", user_data);
    MAC_DEBUG("mac_data_test: parse_user_data = 0x%x\n", parse_user_data);
    MAC_DEBUG("mac_data_test: hdr.src_addr.mode = %d\n", hdr.src_addr.mode);
    MAC_DEBUG("mac_data_test: hdr.dest_addr.mode = %d\n", hdr.dest_addr.mode);
    MAC_DEBUG("mac_data_test: hdr.src_addr = 0x%x\n", (uint32)hdr.src_addr.a.addr64);
    MAC_DEBUG("mac_data_test: hdr.dest_addr = 0x%x\n", (uint32)hdr.dest_addr.a.addr64);
    MAC_DEBUG("mac_data_test: hdr.dest_pan_id = 0x%x\n", hdr.dest_pan_id);
    MAC_DEBUG("mac_data_test: req->dest_pan_id = 0x%x\n", req->dest_pan_id);

    if (user_data != parse_user_data) {
        goto mac_data_req_test;
    }

    if (req->src.mode != hdr.src_addr.mode) {
        goto mac_data_req_test;
    }
    if (req->dest.mode != hdr.dest_addr.mode) {
        goto mac_data_req_test;
    }

    if (req->src.mode == ADDR_64_M) {
        if (req->src.a.addr64 != hdr.src_addr.a.addr64) {
        goto mac_data_req_test;
        }
    } else {
        if (req->src.a.addr16 != hdr.src_addr.a.addr16) {
        goto mac_data_req_test;
        }
    }

    if (req->dest.mode = ADDR_64_M) {
        if (req->dest.a.addr64 != hdr.dest_addr.a.addr64) {
            goto mac_data_req_test;
        }
    } else {
        if (req->dest.a.addr16 != hdr.dest_addr.a.addr16) {
            goto mac_data_req_test;
        }
    }

    if (req->dest_pan_id != hdr.dest_pan_id) {
        goto mac_data_req_test;
    }

    /* compare use data */
    buf_free(send);
    buf_free(recv);
    return MAC_OK;
        
mac_data_req_test:
    buf_free(send);
    buf_free(recv);
    if (req->opt.indir == 1) {
        mac_indir_free(hdr.dsn);
    }
    return MAC_ERR;
}


